import json

import pandas as pd
from langchain_core.output_parsers import JsonOutputParser

from catalog.dip_catalog import DipCatalog
import logging
from util.read_txt_file import ReadTxt
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
import os
from dotenv import load_dotenv
logger = logging.getLogger(__name__)

class DIPSyntheticRules:
    def __init__(self):
        self.synthetic_knowledge = self.load_synthetic_knowledge()

        # 初始化AI模型
        load_dotenv()
        api_key = os.getenv("OPENAI_API_KEY")
        base_url = os.getenv("OPENAI_BASE_URL")
        model_name = os.getenv("MODEL_NAME")

        self.llm = ChatOpenAI(
            temperature=0.1,
            max_tokens=300,
            base_url=base_url,
            model=model_name,
            api_key=api_key
        )

        # 创建综合目录分组提示词模版
        self.synthetic_prompt = ChatPromptTemplate.from_template(
            """你是DIP综合目录分组专家，请根据诊断编码进行综合目录分组。

患者信息：
- 患者姓名：{patient_name}
- 诊断编码：{diagnosis_code}
- 主手术编码：{main_surgery_code}
- 次要手术编码：{other_surgery_code}
- 治疗操作：{treatment_code}
- 治疗操作：{diagnostic_operation}
原始AI分组结果：
{original_result}

综合目录数据：
{synthetic_catalog_data}

综合目录知识库：
{synthetic_knowledge}


请返回JSON格式的结果：

{{
  "分组名称": "调整后的治疗方式名称",
  "分值": 调整后的数值,
  "调整说明": "调整原因和计算过程",
  "综合目录调整完成": true
}}

**重要要求**：
1. 必须返回有效的JSON格式
2. 分值必须是数值类型，不是字符串
3. 不要添加任何JSON之外的文字
4 .按照综合目录主要操作类型列进行匹配
返回JSON："""
        )

        self.json_parser = JsonOutputParser()
        self.synthetic_chain = self.synthetic_prompt | self.llm | self.json_parser

    #检查是否要执行综合目录
    def ai_check_synthetic_agent(self, ai_result,diagnosis_code):
        diagnosis_code_short = diagnosis_code.split(".")[0]

        dipCatalog = DipCatalog()
        catalog_synthetic = dipCatalog.load_base_catalog_excel("综合目录.xlsx","诊断编码", diagnosis_code_short)
        try:
            synthetic_res = json.loads(catalog_synthetic)
        except Exception as e:
            logger.error(f"综合目录 JSON 解析失败: {e}, 原始数据: {catalog_synthetic}")
            return False
        synthetic_record = synthetic_res.get("data", None)
        try:
            if synthetic_record is None:
                return False
            # 检查是否走综合
            if ai_result.get('需要综合目录分析', False):
                return True
            
            return False
        except Exception as e:
            logger.error(f"AI综合目录求失败: {str(e)}")
            return False

    def call_synthetic_agent(self,patient_row,base_result):
        """调用床日智能体"""
        try:
            logger.info(f"调用综合目录")
            dipCatalog = DipCatalog()
            diagnosis_code =patient_row['诊断编码']
            diagnosis_code_short = diagnosis_code.split(".")[0]

            catalog_synthetic = dipCatalog.load_base_catalog_excel("综合目录.xlsx","诊断编码",diagnosis_code_short)

            synthetic_res = json.loads(catalog_synthetic)

            synthetic_catalog_data = synthetic_res["data"]

            synthetic_result = self.analyze_synthetic_invoke(patient_row, base_result, synthetic_catalog_data)

            # 直接返回JSON结果
            return synthetic_result

        except Exception as e:
            logger.error(f"综合目录智能体调用失败: {str(e)}")
            return {"错误": str(e)}
    #调用大模型(执行综合目录分组)
    def analyze_synthetic_invoke(self,patient_row,original_result,synthetic_catalog_data):
        diagnosis_code = patient_row['诊断编码']
        diagnosis_code_short = diagnosis_code.split(".")[0]

        try:
            result = self.synthetic_chain.invoke({
                "patient_name": patient_row['患者姓名'],
                "diagnosis_code": diagnosis_code_short,
                "main_surgery_code": patient_row['主手术'] if pd.notna(patient_row['主手术']) else "",
                "other_surgery_code": patient_row['其它手术'] if pd.notna(patient_row['其它手术']) else "",
                "treatment_code": patient_row['治疗操作'] if pd.notna(patient_row['治疗操作']) else "",
                "diagnostic_operation": patient_row['诊断操作'] if pd.notna(patient_row['诊断操作']) else "",
                "original_result": original_result,
                "synthetic_catalog_data": synthetic_catalog_data,
                "synthetic_knowledge": self.synthetic_knowledge
            })
            logger.info(f"综合目录智能体分析结果: {result}")

            # 如果返回的是字典，直接返回；如果是字符串，尝试解析JSON
            if isinstance(result, dict):
                return result
            elif isinstance(result, str):
                try:
                    return json.loads(result)
                except json.JSONDecodeError:
                    logger.error(f"综合目录智能体返回的不是有效JSON: {result}")
                    return {"错误": "JSON解析失败", "原始结果": result}
            else:
                return {"错误": "未知返回格式", "原始结果": str(result)}

        except Exception as e:
            logger.error(f"综合目录智能体分析失败: {str(e)}")
            return {"错误": f"综合目录调整失败: {str(e)}"}
    #加载综合目录知识库
    def load_synthetic_knowledge(self):
        try:
            reader_txt = ReadTxt('综合目录知识库.txt')
            return reader_txt.load_txt_lines()
        except Exception as e:
            logger.error(f"加载综合目录知识库失败: {str(e)}")
            return ""
